#include <iostream>
using namespace std;

#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include "RockUtiles.h"

// declaration des fonctions

void afficherTerrain(int nbLignes, int nbColonnes);
int recupererTouche();
int calculerDirectionTouche(int touche);
void positionAleatoire(int nbLignes, int nbColonnes, int &posX, int &posY);
void deplacerSerpentI(int direction, int &posX, int &posY);
int saisirNiveau();
void creerSouris(int nbLignes, int nbColonnes,int sourisX[], int sourisY[], int nbSouris);
void afficherSouris(int sourisX[], int sourisY[], int nbSouris);
void deplacerSerpentII(int direction, int serpentX[], int serpentY[],int &tailleSerpent,int sourisX[], int sourisY[], int &nbSouris);
bool testerCollision(int serpentX[], int serpentY[], int nbrelignes, int nbrColonnes, int tailleserpent);

// fonction principale

int main(){

	srand((unsigned int)time(NULL));
	//declaration des variable
	int nbLignes = 30;
	int nbColonnes = 70;
	int touche;
	int direction;
	int directionPrecedent = 0;
	int nbrSouris = 0;
	int sourisX[20], sourisY[20];
	int tailleSerpent = 1;
	int serpentX[70], serpentY[30];
	
	//affichage pour le saise de niveau qui est egale au nombre de souris
	nbrSouris = saisirNiveau();
	system("cls");
	//affichage des fonctions
	afficherTerrain(nbLignes, nbColonnes);
	positionAleatoire(nbLignes, nbColonnes, serpentX[0], serpentY[0]);
	creerSouris(nbLignes, nbColonnes, sourisX, sourisY, nbrSouris);
	afficherSouris(sourisX, sourisY, nbrSouris);

	do{
		touche = recupererTouche();
		direction = calculerDirectionTouche(touche);

		if (direction == -1){
			direction = directionPrecedent;
		}
		directionPrecedent = direction;

		deplacerSerpentII(direction, serpentX, serpentY, tailleSerpent, sourisX, sourisY, nbrSouris);

	} while (testerCollision(serpentX, serpentY, nbLignes, nbColonnes, tailleSerpent));
		gotoXY(1, 30);

	 cout<<"GAME OVER "<<endl;


}


// ************
// * PARTIE I *
// ************
void afficherTerrain(int nbLignes, int nbColonnes){
	cadre (0,0,70,30,5);
}

int recupererTouche(){
	int symbol;
	if (_kbhit()){
		symbol = _getch();
	}
	else {
		symbol = -1;
	}

	return symbol;
}

int calculerDirectionTouche(int touche){

	int direction;

	switch (touche){
	case 'd':
		direction = 0;
		break;
	case 'a':
	case 'q':
		direction = 1;
		break;
	case 'w':
	case 'z':
		direction = 2;
		break;
	case 's':
		direction = 3;
		break;
	default: direction = -1;
		break;
	}

	return direction;
}

void positionAleatoire(int nbLignes, int nbColonnes, int &posX, int &posY){

	
	int xmax = nbColonnes - 1;
	int ymax = nbLignes - 1;

	posX = 1 + rand() % xmax;
	posY = 1 + rand() % ymax;
}

void deplacerSerpentI(int direction, int &posX, int &posY){



	if (direction == 0){
		gotoXY(++posX, posY);
		cout << '*';
	}
	else if (direction == 1){

		gotoXY(--posX, posY);
		cout << '*';
	}
	else if (direction == 2){

		gotoXY(posX, --posY);
		cout << '*';
	}
	else if (direction == 3){

		gotoXY(posX, ++posY);
		cout << '*';
	}
}


// *************
// * PARTIE II *
// *************

int saisirNiveau(){
	int niveau = 0;
	bool valid;
	do
	{
		valid = true;
		cout << "Saisir niveau : ";
		cin >> niveau;
		if ( niveau<1 || niveau>20)
		{
			
			valid = false;
		}
	} while (!valid);
	return niveau;
}


void creerSouris(int nbLignes, int nbColonnes,int sourisX[], int sourisY[], int nbSouris){
	int posx, posy;
	for (int i = 0; i < nbSouris; i++)
	{
		posx = 0;
		posy = 0;
		positionAleatoire(nbLignes, nbColonnes, posx, posy);
		sourisX[i] = posx;
		sourisY[i] = posy;

	}


}

void afficherSouris(int sourisX[], int sourisY[], int nbSouris){
	int posx, posy;
	for (int i = 0; i < nbSouris; i++)
	{
		posx = sourisX[i];
		posy = sourisY[i];
		gotoXY(posx, posy);
		cout << "#";
	}

}
void deplacerSerpentII(int direction, int serpentX[], int serpentY[],int &tailleSerpent,int sourisX[], int sourisY[], int &nbSouris){

	for (int i = 0; i < tailleSerpent; i++){
		gotoXY(serpentX[i], serpentY[i]);
		cout << ' ';
	}

	int posX0 = serpentX[0];
	int posY0 = serpentY[0];

	for (int i = tailleSerpent - 1; i > 0; i--){
		serpentX[i] = serpentX[i - 1];
		serpentY[i] = serpentY[i - 1];
	}

	switch (direction)
	{
	case 0:
		serpentX[0] = ++posX0;
		break;
	case 1:
		serpentX[0] = --posX0;
		break;
	case 2:
		serpentY[0] = --posY0;
		break;
	case 3:
		serpentY[0] = ++posY0;
		break;
	}

	for (int i = 0; i < nbSouris; i++){
		if (serpentX[0] == sourisX[i] && serpentY[0] == sourisY[i]){
			tailleSerpent++;
			switch (direction)
			{
			case 0:
				serpentX[tailleSerpent - 1] = serpentX[tailleSerpent - 2] - 1;
				serpentY[tailleSerpent - 1] = serpentY[tailleSerpent - 2];
				break;
			case 1:
				serpentX[tailleSerpent - 1] = serpentX[tailleSerpent - 2] + 1;
				serpentY[tailleSerpent - 1] = serpentY[tailleSerpent - 2];
				break;
			case 2:
				serpentX[tailleSerpent - 1] = serpentX[tailleSerpent - 2];
				serpentY[tailleSerpent - 1] = serpentY[tailleSerpent - 2] + 1;
				break;

			case 3:
				serpentX[tailleSerpent - 1] = serpentX[tailleSerpent - 2];
				serpentY[tailleSerpent - 1] = serpentY[tailleSerpent - 2] - 1;
				break;
			}
			sourisX[i] = -100;
			sourisY[i] = -100;
		}
	}

	for (int i = 0; i < tailleSerpent; i++){
		gotoXY(serpentX[i], serpentY[i]);
		cout << '*';
	}

	Sleep(250);
}



bool testerCollision(int serpentX[], int serpentY[], int nbrelignes, int nbrColonnes, int tailleserpent){
	bool colle = true;
	int i = 1;

	//collision sur le mur
	if (serpentX[0] == 1 || serpentX[0] == nbrColonnes || serpentY[0] == 0 || serpentY[0] == nbrelignes)
	{
		colle = false;
		return colle;
	}

	//collision entre lui meme
	do
	{
		if (serpentX[0] == serpentX[i] && serpentY[0] == serpentY[i])
			colle = false;
		i++;
	} while (colle && i<tailleserpent);
	return colle;

}
